feat: add typed distribution event catalog with opt-in emit-time validation#3
Conversation
…dation - src/catalog.ts: EventTypeCatalog registry binding envelope type strings to @hasna/contracts schema ids (release.published, release.rollout.started/ completed/failed, app.installed, announcement.sent, feedback.created, feedback.triaged) with dependency-free structural payload validators and vendored payload type mirrors - EventsClient: optional catalog + validateCatalogTypes options and a per-emit validate override; invalid registered-type payloads throw EventValidationError before the event is stored or delivered - backward compatible: validation is off by default and unregistered free-form event types always pass - export ./catalog subpath, build entry, README docs, and unit tests for both validation directions
|
OpenLoops worker review: not merging yet. Validation on the amended PR head
I pushed one scoped docs correction ( Remaining merge blockers from adversarial review:
To unblock: either make the validators and schema metadata true contract mirrors, or change the public API/docs so these are clearly minimal event payload validators and remove/avoid nonexistent contract schema ids. Empty GitHub checks/reviewDecision are not policy blockers here ( |
|
Blocking merge for now after local validation plus independent adversarial review. Validation evidence on a no-commit merge of
Merge blockers:
Recommended fix before merge: either align |
What
Implements the
@hasna/eventshalf of the distribution apps plan foundation (Lane A): a typed event catalog module binding envelopetypestrings to the@hasna/contractsdistribution schemas, plus an OPT-IN emit-time validator hook.src/catalog.ts(exported from the root and as@hasna/events/catalog):DISTRIBUTION_EVENT_TYPES:release.published,release.rollout.started|completed|failed,app.installed,announcement.sent,feedback.created,feedback.triaged.DISTRIBUTION_EVENT_CONTRACT_SCHEMAS: maps each type to the contracts schema itsdatapayload mirrors (hasna.release.v1,hasna.rollout_record.v1,hasna.announcement.v1,hasna.feedback.v1).ReleasePublishedData,RolloutData,AppInstalledData,AnnouncementSentData,FeedbackCreatedData,FeedbackTriagedData) and dependency-free structural validators — no runtime dependency on@hasna/contracts(this package stays commander-only).EventTypeCatalogregistry (register/unregister/validateEvent/assertEventValid),EventValidationError,registerDistributionEventTypes().EventsClient: newcatalog+validateCatalogTypesoptions and a per-emitvalidateoverride. When enabled, registered types with invalid payloads throwEventValidationErrorBEFORE the event is stored or delivered.Backward compatibility (~50 dependent packages)
Verification
bun run typecheck: passbun test: 61 pass, 0 fail, 264 expect() calls across 8 files (includes catalog validator tests both ways: off-by-default emits bad payloads untouched; opt-in rejects before store; free-form types pass; per-emit override in both directions)bun run build: pass (catalog.js entry emitted)Follow-ups
@hasna/contractsversion publishes, an optional zod-backed adapter could replace the structural validators for consumers that want full contract validation.